#ifndef xpack_test_lang_cxx_parse
#define xpack_test_lang_cxx_parse
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::test_lang_cxx_parse::inc
#include"test/helper.hpp" // 需要放第一
#include"lang/cxx/parse.hpp"
#include"lang/cxx.hpp"
#include"utils/array.hpp"
#pragma pop_macro("xuser")

namespace mixc::test_lang_cxx_parse{
    xtest("parse"){
        inc::c08 w = "2020";
        union{
            u32 u = 2020;
            i32 i;
            u64 ux;
            i64 ix;
        };

        {
            auto result = w.parse<u32>();
            xassert_eq(u , u32(result));
            xassert_eq(true , result->is_parsed_completely);
            xassert_eq(not_exist, result->index_of_error);
        }

        struct pair{ inc::c08 str; u64 v; };
        auto && v = inc::make_array(
            pair { "0" , 0  },
            pair { "1" , 1  },
            pair { "2" , 2  },
            pair { "3" , 3  },
            pair { "4" , 4  },
            pair { "5" , 5  },
            pair { "6" , 6  },
            pair { "7" , 7  },
            pair { "8" , 8  },
            pair { "9" , 9  },
            pair { "00", 0  },
            pair { "01", 1  },
            pair { "02", 2  },
            pair { "03", 3  },
            pair { "04", 4  },
            pair { "05", 5  },
            pair { "06", 6  },
            pair { "07", 7  },
            pair { "08", 8  },
            pair { "09", 9  },
            pair { "10", 10 },
            pair { "11", 11 },
            pair { "12", 12 },
            pair { "13", 13 },
            pair { "14", 14 },
            pair { "15", 15 },
            pair { "16", 16 },
            pair { "17", 17 },
            pair { "18", 18 },
            pair { "19", 19 },
            pair { "123", 123 },
            pair { "1234", 1234 },
            pair { "12345", 12345 },
            pair { "123456", 123456 },
            pair { "1234567", 1234567 },
            pair { "12345678", 12345678 },
            pair { "123456789", 123456789 },
            pair { "4294967293", 4294967293 },
            pair { "4294967294", 4294967294 },
            pair { "4294967295", 4294967295 },

            pair { "+4294967295", 4294967295 },
            pair { "+4294967294", 4294967294 },
            pair { "+4294967293", 4294967293 },
            pair { "+123456789", 123456789 },
            pair { "+12345678", 12345678 },
            pair { "+1234567", 1234567 },
            pair { "+123456", 123456 },
            pair { "+12345", 12345 },
            pair { "+1234", 1234 },
            pair { "+123", 123 },
            pair { "+19", 19 },
            pair { "+18", 18 },
            pair { "+17", 17 },
            pair { "+16", 16 },
            pair { "+15", 15 },
            pair { "+14", 14 },
            pair { "+13", 13 },
            pair { "+12", 12 },
            pair { "+11", 11 },
            pair { "+10", 10 },
            pair { "+09", 9  },
            pair { "+08", 8  },
            pair { "+07", 7  },
            pair { "+06", 6  },
            pair { "+05", 5  },
            pair { "+04", 4  },
            pair { "+03", 3  },
            pair { "+02", 2  },
            pair { "+01", 1  },
            pair { "+00", 0  },
            pair { "+9" , 9  },
            pair { "+8" , 8  },
            pair { "+7" , 7  },
            pair { "+6" , 6  },
            pair { "+5" , 5  },
            pair { "+4" , 4  },
            pair { "+3" , 3  },
            pair { "+2" , 2  },
            pair { "+1" , 1  },
            pair { "+0" , 0  }
        );

        for(uxx i = 0; i < v->length; i++){
            auto u = v[i].v;
            auto result = v[i].str.parse<u32>();
            xassert_eq(u, u32(result));
            xassert_eq(true, result->is_parsed_completely);
            xassert_eq(not_exist, result->index_of_error);
        }

        {
            w = "-1";
            i = -1;
            auto result = w.parse<i32>();
            xassert_eq(i, i32(result));
            xassert_eq(true, result->is_parsed_completely);
            xassert_eq(not_exist, result->index_of_error);
        }

        {
            w = "-2147483648";
            i = -2147483648;
            auto result = w.parse<i32>();
            xassert_eq(i, i32(result));
            xassert_eq(true, result->is_parsed_completely);
            xassert_eq(not_exist, result->index_of_error);
        }

        {
            w = "-9223372036854775808";
            ix = -9223372036854775807LL - 1;
            auto result = w.parse<i64>();
            xassert_eq(ix, i64(result));
            xassert_eq(true, result->is_parsed_completely);
            xassert_eq(not_exist, result->index_of_error);
        }


        {
            auto str = inc::c08{};
            auto result = inc::c08(" miaogu").parse(str);
            xassert_eq(result->index_of_error, not_exist);
            xassert_eq(result, 1u);
            xassert_eq(str, "miaogu");
        }

        {
            auto a = ixx{};
            auto b = f32{};
            auto c = ixx{};
            auto d = inc::c08{};
            auto e = char{};
            auto f = char{};
            auto result = inc::c08("123 -1.5 -12 hello ef").parse("\v \v \v \v \v \v", a, b, c, d, e, f);
            xassert_eq(result->index_of_error, not_exist);
            xassert_eq(result, 6u);
            xassert_eq(a, 123);
            xassert_eq(b, -1.5f);
            xassert_eq(c, -12);
            xassert_eq(d, "hello");
            xassert_eq(e, 'e');
            xassert_eq(f, 'f');
        }

        {
            auto a = ixx{};
            auto b = f32{};
            auto c = ixx{};
            auto d = inc::c08{};
            auto result = inc::c08("-123 +1.5 12 hello ").parse("\v \v \v \v", a, b, c, d);
            xassert_eq(result->index_of_error, not_exist);
            xassert_eq(result, 4u);
            xassert_eq(a, -123);
            xassert_eq(b, 1.5f);
            xassert_eq(c, 12);
            xassert_eq(d, "hello");
        }

        {
            auto a = ixx{};
            auto b = f32{};
            auto c = ixx{};
            auto d = inc::c08{};
            auto result = inc::c08("123 +1.5 -12 hello").parse(a, b, c, d);
            xassert_eq(result->index_of_error, not_exist);
            xassert_eq(result, 4u);
            xassert_eq(a, 123);
            xassert_eq(b, 1.5f);
            xassert_eq(c, -12);
            xassert_eq(d, "hello");
        }

        {
            auto age = ixx{};
            auto name = inc::c08{};
            auto result = inc::c08("name=cat age=12").parse("name=\v age=\v", name, age);
            xassert_eq(result->index_of_error, not_exist);
            xassert_eq(result, 2u);
            xassert_eq(name, "cat");
            xassert_eq(age, 12);
        }

        {
            auto name = inc::c08{};
            auto port = ixx{};
            ixx  ip[4] = {};
            auto result = inc::c08("name=eth0, port=443, ip=192.168.1.2").parse("name=\v, port=\v, ip=\v.\v.\v.\v", name, port, ip[0], ip[1], ip[2], ip[3]);
            xassert_eq(result->index_of_error, not_exist);
            xassert_eq(result, 6u);
            xassert_eq(name, "eth0");
            xassert_eq(port, 443);
            xassert_eq(ip[0], 192);
            xassert_eq(ip[1], 168);
            xassert_eq(ip[2], 1);
            xassert_eq(ip[3], 2);
        }

        {
            auto name = inc::c08{};
            auto result = inc::c08("name=eth0\n").parse("name=\v\n", name);
            xassert_eq(result->index_of_error, not_exist);
            xassert_eq(result, 1u);
            xassert_eq(name, "eth0");
        }

        {
            auto name = inc::c08{};
            auto result = inc::c08("name=eth0\r").parse("name=\v\r\n", name);
            xassert_eq(result->index_of_error, 10u);
            xassert_eq(result, 1u);
            xassert_eq(name, "eth0");
        }

        // 异常情况
        {
            auto name = inc::c08{};
            auto port = ixx{};
            auto result = inc::c08("name=eth0\v").parse("name=\v\v", name, port);
            xassert_eq(result->index_of_error, 10u);
            xassert_eq(result, 1u);
            xassert_eq(name, "eth0\v");
        }

        // 设置属性
        {
            auto foo = inc::c08("bala bala");
            auto result = inc::c08("4").parse(foo->length);
            xassert_eq(result->index_of_error, not_exist);
            xassert_eq(result, 1u);
            xassert_eq(foo->length, 4u);
        }
    };
}

#endif